/*
 * Copyright 2009 Eat Local Food, LLC
 * Copyright (c) 2007 osCommerce (this file was written after
 * code review of osCommerce).
 *
 * This file is part of gwtCommerce.
 *
 * gwtCommerce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * gwtCommerce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gwtCommerce.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.elf.gwt.store.client.components;

import com.elf.gwt.common.client.access.RequestParameter;
import com.elf.gwt.common.client.callback.SubComponentCallback;
import com.elf.gwt.common.client.model.AccountMetaModel;
import com.elf.gwt.common.client.model.AccountModel;
import com.elf.gwt.common.client.model.AddressModel;
import com.elf.gwt.common.client.subcomponent.CommonSubComponent;
import com.elf.gwt.common.client.subcomponent.SwitchToSSLSubComponent;
import com.elf.gwt.common.client.utils.CommonUtils;
import com.elf.gwt.store.client.StoreComponentController;
import com.elf.gwt.store.client.subcomponents.AccountAddressSubComponent;
import com.elf.gwt.store.client.subcomponents.AccountCreateSubComponent;
import com.elf.gwt.store.client.subcomponents.AccountLoginSubComponent;
import com.elf.gwt.store.client.subcomponents.AccountViewSubComponent;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 *  
 */
public class AccountComponent extends JSONServerComponent
{		
	public static final String LoginAccount = "LoginAccount";
	public static final String LogoffAccount = "LogoffAccount";
	public static final String CreateAccount = "CreateAccount";
	public static final String ViewAccount = "ViewAccount";
	public static final String EditAccount = "EditAccount";
	public static final String ChangePassword = "ChangePassword";
	public static final String AddressBook = "AddressBook";
	public static final String DeleteAddress = "DeleteAddress";
	public static final String ViewOrders = "ViewOrders";
	public static final String PasswordForgotten = "PasswordForgotten";

	protected String action = "";
	protected String token = "";
	protected String subToken = "";

	protected AccountMetaModel accountMetaModel;

	protected VerticalPanel bodyPanel;

	protected AccountLoginSubComponent loginForm;
	protected AccountCreateSubComponent createForm;
	protected AccountCreateSubComponent editForm;
	protected AccountCreateSubComponent passwordForm;
	protected AccountViewSubComponent viewForm;
	protected AccountAddressSubComponent addressForm;
	protected AccountModel accountModel;


	/**
	 * Constructor
	 */
	public AccountComponent(StoreComponentController controller, String stylePrefix)
	{
		super(controller, stylePrefix, null, false);
		setupTimer();
		panel.setText(0, 0, controller.getStoreConstants().AccountComponentSigninTitle());
		panel.setWidth("100%");
		bodyPanel = new VerticalPanel();
		bodyPanel.setWidth("100%");
		bodyPanel.addStyleName("ComponentBodyPanel");
		bodyPanel.addStyleName(getHandle() + "BodyPanel");
		panel.setWidget(1, 0, bodyPanel);
		loginForm = null;
		createForm = null;
		accountModel = new AccountModel(StoreComponentController.cartComponent.getCartModel());
	}

	public boolean updateFromHistoryParameters(String[] params)
	{
		if (!CommonUtils.isSSL())
		{
			CartComponent cartComponent = (CartComponent)controller.getComponent("CartComponent");
			SwitchToSSLSubComponent ssl = new SwitchToSSLSubComponent(storeController, controller.getHistoryToken(), cartComponent.getCartModel().getCartContents());
			panel.setWidget(1, 0, ssl);
			ssl.submit();
		}
		action = "";
		token = "";
		subToken = "";

		if (params.length > 1) action = params[1];
		controller.hideComponents();
		if (action.equals(LoginAccount) || action.equals(CreateAccount)) 
		{
			if (params.length > 2) {
				subToken = params[2];
				token = "AccountComponent--" + action + "--" + subToken;
			}
			else {
				token = "AccountComponent--" + action;
			}
		}
		else if (action.equals(LogoffAccount))
		{
			createForm = null;
			editForm = null;
			passwordForm = null;
			viewForm = null;
			addressForm = null;
			accountModel.update();
			accountModel.setId(-130);
			controller.setLoggedIn(false);
			StoreComponentController.cartComponent.getCartModel().clearProducts();
			storeController.removeComponent("CheckoutComponent");
			controller.getComponent("HeaderComponent").build();
			controller.getComponent("CartSummaryComponent").build();
			onSelection("AccountComponent--LoginAccount");
		}

		controller.hideComponents();
		try {buildFromModel();}catch(Exception e){}
		return false;
	}

	public void additionalRequestParameters()
	{
		AddressModel addressModel = accountModel.getDefaultAddress();
		if (action.contains("Address")) addressModel = accountModel.getEditAddress();

		if (action.contains("Address"))
		{
			addRequestParameter(new RequestParameter("addressId", addressModel.getId()));
		}

		if (action.equals(PasswordForgotten))
		{
			addRequestParameter(new RequestParameter("email_address", accountModel.getEmailAddress()));
		}

		if (action.equals(LoginAccount))
		{
			addRequestParameter(new RequestParameter("token", token));
		}

		if (action.equals(CreateAccount) || action.equals(LoginAccount))
		{
			addRequestParameter(new RequestParameter("token", token));
			addRequestParameter(new RequestParameter("email_address", accountModel.getEmailAddress()));
			addRequestParameter(new RequestParameter("password", accountModel.getPassword()));
			addRequestParameter(new RequestParameter("cart", StoreComponentController.cartComponent.getCartModel().getCartContents()));
		}

		if (action.equals(CreateAccount) || action.equals(EditAccount))
		{
			if (accountMetaModel.isDisplayGender())addRequestParameter(new RequestParameter("gender", accountModel.getGender()));
			addRequestParameter(new RequestParameter("firstname", accountModel.getFirstname()));
			addRequestParameter(new RequestParameter("lastname", accountModel.getLastname()));
			if (accountMetaModel.isDisplayDOB()) addRequestParameter(new RequestParameter("dob", accountModel.getDateOfBirth()));
			addRequestParameter(new RequestParameter("email_address", accountModel.getEmailAddress()));
			addRequestParameter(new RequestParameter("telephone", accountModel.getTelephone()));
			addRequestParameter(new RequestParameter("fax", accountModel.getFax()));
		}

		if (action.equals(CreateAccount) || action.equals(AddressBook))
		{
			if (accountMetaModel.isDisplayGender())addRequestParameter(new RequestParameter("gender", addressModel.getGender()));
			addRequestParameter(new RequestParameter("firstname", addressModel.getFirstname()));
			addRequestParameter(new RequestParameter("lastname", addressModel.getLastname()));
			if (accountMetaModel.isDisplayCompany()) addRequestParameter(new RequestParameter("company", addressModel.getCompany()));
			addRequestParameter(new RequestParameter("country", addressModel.getCountry()));
			addRequestParameter(new RequestParameter("street_address", addressModel.getStreet()));
			if (accountMetaModel.isDisplaySuburb()) addRequestParameter(new RequestParameter("suburb", addressModel.getSuburb()));
			addRequestParameter(new RequestParameter("postcode", addressModel.getPostcode()));
			addRequestParameter(new RequestParameter("city", addressModel.getCity()));
			if (accountMetaModel.isDisplayState()) addRequestParameter(new RequestParameter("state", addressModel.getState()));
		}

		if (action.equals(CreateAccount))
		{
			addRequestParameter(new RequestParameter("newsletter", accountModel.isNewsletter()));
			addRequestParameter(new RequestParameter("captcha_code", accountModel.getCaptchaCode()));
			addRequestParameter(new RequestParameter("captcha_session", accountModel.getCaptchaSession()));
		}

		if (action.equals(CreateAccount) || action.equals(ChangePassword))
		{
			addRequestParameter(new RequestParameter("password", accountModel.getPassword()));
			accountModel.setPassword("");
		}

		if (action.length() > 0)
			addRequestParameter(new RequestParameter("action", action));
	}

	protected void buildMetaModel(JSONObject jsonObject)
	{
		accountMetaModel = new AccountMetaModel(jsonObject);
		accountModel.setAccountMetaModel(accountMetaModel);
	}

	protected void buildModel(JSONObject jsonObject)
	{
		accountModel.update(jsonObject, accountMetaModel);
		controller.setLoggedIn(accountModel.getId() > 0);
		controller.getComponent("HeaderComponent").build();
	}

	public void buildFromModel() throws Exception
	{	
		if (accountModel.getId() < 1)
		{
			if (action == null || action.length() == 0) {
				onBuilt();
				setVisible(false);
				return;
			}

			if (!(action.equals(LoginAccount) || action.equals(CreateAccount))) action = LoginAccount;

			if (action.equals(CreateAccount))
			{
				panel.setText(0, 0, storeController.getStoreConstants().AccountComponentCreateTitle());
				bodyPanel.clear();
				accountModel.setHistoryAction(action);
				buildCreateAccount();
			}
			else
			{
				panel.setText(0, 0, storeController.getStoreConstants().AccountComponentSigninTitle());
				bodyPanel.clear();
				accountModel.setHistoryAction(LoginAccount);
				buildLoginAccount();
			}
		}
		else
		{			
			if (subToken != null && subToken.length() > 0)
			{
				String[] split = subToken.split("__");
				String historyToken = split[0];
				for (int i = 1; i < split.length; i++)
				{
					historyToken += "--" + split[i];
				}
				controller.getComponent("HeaderComponent").build();
				onSelection(historyToken);
				return;
			}

			if (action.equals(LoginAccount) || action.equals(CreateAccount)) {
				onSelection("AccountComponent--" + ViewAccount);
			}

			if (action.equals(ViewAccount))
			{
				controller.getComponent("HeaderComponent").build();
				accountModel.setErrorCode(0);
				panel.setText(0, 0, storeController.getStoreConstants().AccountComponentAccountTitle());
				bodyPanel.clear();
				accountModel.setHistoryAction(action);
				buildViewAccount();
			}
			else if (action.equals(EditAccount))
			{
				panel.setText(0, 0, storeController.getStoreConstants().AccountComponentEditTitle());
				bodyPanel.clear();
				accountModel.setHistoryAction(action);
				buildEditAccount();
			}
			else if (action.equals(AddressBook) || action.equals(DeleteAddress))
			{
				panel.setText(0, 0, storeController.getStoreConstants().AccountComponentMyPersonalAddressBook());
				bodyPanel.clear();
				accountModel.setHistoryAction(AddressBook);
				buildAddressBook();
			}
			else if (action.equals(ChangePassword))
			{
				panel.setText(0, 0, storeController.getStoreConstants().AccountComponentChangePasswordTitle());
				bodyPanel.clear();
				accountModel.setHistoryAction(action);
				buildChangePassword();
			}
			else if (action.equals(ViewOrders))
			{
			}
			Window.scrollTo(0, 0);

		}
		accountModel.setTitle(panel.getText(0,0));
		onBuilt();
	}

	public String getTitle()
	{
		return panel.getText(0,0);
	}

	protected void buildLoginAccount() throws Exception
	{
		panel.setText(0, 0, storeController.getStoreConstants().AccountComponentSigninTitle());

		if (loginForm == null)
		{
			loginForm = new AccountLoginSubComponent(
					storeController, 
					subComponentCallback);
		}
		loginForm.build();
		bodyPanel.add(loginForm);
	}

	protected void buildCreateAccount() throws Exception
	{
		if (createForm == null) {
			createForm = new AccountCreateSubComponent(
					storeController,
					accountModel.getDefaultAddress(),
					subComponentCallback, 
					CreateAccount);
		}
		else {
			createForm.setSuperAction(CreateAccount);
		}
		createForm.build();
		bodyPanel.add(createForm);
	}

	protected void buildEditAccount() throws Exception
	{
		if (editForm == null) {
			editForm = new AccountCreateSubComponent(
					storeController,
					accountModel.getDefaultAddress(),
					subComponentCallback, 
					EditAccount);
		}
		else {
			editForm.setSuperAction(EditAccount);
		}
		editForm.build();
		bodyPanel.add(editForm);
	}

	protected void buildChangePassword() throws Exception
	{
		if (passwordForm == null) {
			passwordForm = new AccountCreateSubComponent(
					storeController,
					null,
					subComponentCallback, 
					ChangePassword);
		}
		else {
			passwordForm.setSuperAction(ChangePassword);
		}
		passwordForm.build();
		bodyPanel.add(passwordForm);
	}

	protected void buildViewAccount() throws Exception
	{
		if (viewForm == null) {
			viewForm = new AccountViewSubComponent(
					storeController,
					subComponentCallback,
					action);
		}
		else {
			viewForm.setSuperAction(action);
		}
		bodyPanel.add(viewForm);
	}

	protected void buildAddressBook() throws Exception
	{
		if (addressForm == null) {
			addressForm = new AccountAddressSubComponent(
					storeController,
					subComponentCallback, 
					AddressBook);
		}
		else {
			addressForm.setSuperAction(AddressBook);
			addressForm.build();
		}
		bodyPanel.add(addressForm);
	}

	protected SubComponentCallback subComponentCallback = 
		new SubComponentCallback() {

		public void onNavigate(CommonSubComponent subComponent) {
			action = subComponent.getSuperAction();
			String successToken = getSubToken();
			if (successToken.length() > 0) successToken = "--" + successToken;
			onSelection("AccountComponent--" + action + successToken);
		}

		public void onSuccess(CommonSubComponent subComponent) {
			action = subComponent.getSuperAction();
			build(true);
		}

		public void onError(CommonSubComponent subComponent, Throwable exception) {}
	};

	public AccountModel getAccountModel() {
		return accountModel;
	}

	public AccountMetaModel getAccountMetaModel() {
		return accountMetaModel;
	}

	public String getAction() {
		return action;
	}

	public void setAction(String action) {
		this.action = action;
	}

	public String getToken() {
		return token;
	}

	public String getSubToken() {
		return subToken;
	}
}
